package com.michaelbulava.TFS.ui.controls.connect;

import com.michaelbulava.TFS.ui.controls.generic.CheckboxTable;
import com.microsoft.tfs.core.clients.commonstructure.ProjectInfo;
import com.microsoft.tfs.core.clients.versioncontrol.SourceControlCapabilityFlags;
import com.microsoft.tfs.util.Check;

import javax.swing.*;
import javax.swing.table.TableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

/**
 * Created by mbulava on 6/19/2015.
 */
public class TeamProjectTable extends CheckboxTable<ProjectInfo> {
    //private TeamProjectTableModel tableModel;
    private static final ProjectInfo SELECT_ALL_SPECIAL_PROJECT_INFO =
            new ProjectInfo("(Select All)"//Messages.getString("TeamProjectTable.SelectAll")
                    , "TeamProjectTable://SpecialItems/SelectAll");

    private SourceControlCapabilityFlags sourceControlCapabilityFlagsFilter = SourceControlCapabilityFlags.TFS;

    private RowSorter<TableModel> sorter;

    //Comparator<String> String  = String.CASE_INSENSITIVE_ORDER;

    Comparator<String> sorterComparator = new Comparator<String>() {
        @Override
        public int compare(String o1, String  o2) {
            if (o1.equals(SELECT_ALL_SPECIAL_PROJECT_INFO.getName()))
                return -1;
            if (o2.equals(SELECT_ALL_SPECIAL_PROJECT_INFO.getName()))
                return 1;
            return String.CASE_INSENSITIVE_ORDER.compare(o1, o2);
        }
    };



    public TeamProjectTable(){
        super();

//        sorter = new TableRowSorter<TableModel>(getModel()){
//            @Override
//            public Comparator<?> getComparator(int column) {
//                if (column == getCheckboxItemColumnIndex()){
//                    return sorterComparator;
//                } else {
//                    return super.getComparator(column);
//                }
//            }
//        };
//        setRowSorter(sorter);
        this.getRowSorter().toggleSortOrder(0);
        this.setTableHeader(null);
    }

    @Override
    protected Comparator<?> getSorterComparator(){
        return sorterComparator;
    }

    private CheckItemsStateChangedListener listener;

    public void setCheckItemsStateChangeListener(CheckItemsStateChangedListener value){
        listener = value;
    }

    public interface CheckItemsStateChangedListener{
        void onCheckItemsStateChanged();
    }

    @Override
    protected void CheckboxItemStateChanges(CheckboxItem<ProjectInfo> item){
        if (item.getItem().equals(SELECT_ALL_SPECIAL_PROJECT_INFO) && item.isSelected()){
            setCheckedListItems(removeNotValidVC(TeamProjectTable.this.getProjects()));
        }
        if (listener != null)
            listener.onCheckItemsStateChanged();
    }

    @Override
    protected CheckboxItem<ProjectInfo> createNewCheckBoxItem(ProjectInfo item) {
        return new ProjectInfoCheckBox(item);
    }

    @Override
    protected Class getClassForColumn(int columnIndex) {
        //This shouldn't be used since we only have 1 column
        return String.class;
    }

    @Override
    protected Object getColumnValue(int columnIndex, ProjectInfo item) {
        //This shouldn't be used since we only have 1 column
        return null;
    }

    @Override
    protected String[] getColumnNames() {
        String[] columns = new String[] { "Project" /*Messages.getString("TeamProjectTable.ColumnNameProject")*/ };
        return columns;
    }

    @Override
    protected int getCheckboxItemColumnIndex() {
        return 0;
    }


    public SourceControlCapabilityFlags getSourceControlCapabilityFlags(){
        return this.sourceControlCapabilityFlagsFilter;
    }

    public void setSourceControlCapabilityFlags(SourceControlCapabilityFlags sourceControlCapabilityFlagsFilter){
        this.sourceControlCapabilityFlagsFilter = sourceControlCapabilityFlagsFilter;
    }

    public void clearProjects(){
        setData(addSelectAllItem(removeNotValidVC(null)));
    }
    public void setProjects(ProjectInfo[] projects){
        if (projects == null)
            return;
        setData(addSelectAllItem(removeNotValidVC(projects)));
        updateSelectAllCheckState();
    }

    public ProjectInfo[] getProjects(){
        return removeSelectAllItem(getAllListItems().toArray(new ProjectInfo[0]));
    }

    public int getProjectCount(){
        return getProjects().length;
    }

    public void setCheckedProjects(ProjectInfo[] projects){
        ProjectInfo[] filteredProjects = removeSelectAllItem(projects);
        super.setCheckedListItems(filteredProjects);
        updateSelectAllCheckState();
    }

    public ProjectInfo[] removeSelectAllItem(ProjectInfo[] projects){
        List<ProjectInfo> ret = new ArrayList<ProjectInfo>();
        if (projects != null){
            for (ProjectInfo project : projects){
                if (!SELECT_ALL_SPECIAL_PROJECT_INFO.equals(project))
                    ret.add(project);
            }
        }
        return ret.toArray(new ProjectInfo[0]);
    }

    public ProjectInfo[] addSelectAllItem(ProjectInfo[] projects){
        if ((projects == null) || (projects.length == 0)) {
            return projects;
        }
        for (int i = 0; i < projects.length; i++) {
            if (SELECT_ALL_SPECIAL_PROJECT_INFO.equals(projects[i])) {
                return projects;
            }
        }
        ProjectInfo[] copy = new ProjectInfo[projects.length + 1];
        for (int i = 0; i < projects.length; i++) {
            copy[i] = projects[i];
        }
        copy[(copy.length - 1)] = SELECT_ALL_SPECIAL_PROJECT_INFO;

        return copy;
    }

    public ProjectInfo[] getCheckedProjects(){
        return removeSelectAllItem(getCheckedListItems().toArray(new ProjectInfo[0]));
    }

    private ProjectInfo[] removeNotValidVC(ProjectInfo[] projects){
        List<ProjectInfo> filteredProjects = new ArrayList<ProjectInfo>();
        if (projects != null) {
            for (ProjectInfo project : projects) {
                if (hasValidVC(project)) {
                    filteredProjects.add((ProjectInfo)project);
                }
            }
        }
        return (ProjectInfo[])filteredProjects.toArray(new ProjectInfo[filteredProjects.size()]);
    }

    private int getValidCheckedProjectsCount(){
        return removeNotValidVC(getCheckedProjects()).length;
    }

    private boolean isTfsProject(ProjectInfo item){
        return item.getSourceControlCapabilityFlags().contains(SourceControlCapabilityFlags.TFS);
    }

    private boolean isGitProject(ProjectInfo item){
        return item.getSourceControlCapabilityFlags().contains(SourceControlCapabilityFlags.GIT);
    }

    private boolean hasValidVC(ProjectInfo item){
        Check.notNull(this.sourceControlCapabilityFlagsFilter, "sourceControlCapabilityFlagsFilter");

        return sourceControlCapabilityFlagsFilter.containsAny(item.getSourceControlCapabilityFlags());
    }

    private void updateSelectAllCheckState(){
        int checkedCount = getValidCheckedProjectsCount();
        int elementCount = removeNotValidVC(getProjects()).length;
        ProjectInfoCheckBox selectAll = (ProjectInfoCheckBox) super.getCheckboxItem(SELECT_ALL_SPECIAL_PROJECT_INFO);
        if (selectAll == null)
            return;
        if (checkedCount == elementCount && elementCount > 0){
            //Check and UnGrey
            selectAll.setSelected(true);
            selectAll.setEnabled(false);
        } else if (checkedCount == 0){
            //UnCheck and UnGrey
            selectAll.setSelected(false);
            selectAll.setEnabled(false);
        } else {
            //Check and Grey
            selectAll.setSelected(true);
            selectAll.setEnabled(true);
        }
    }

    private class ProjectInfoCheckBox extends CheckboxItem<ProjectInfo> {

        public ProjectInfoCheckBox(ProjectInfo item) {
            super(item);
            super.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {

                }
            });
        }

        @Override
        protected String getTextForItem() {
            return getItem().getName();
        }

        @Override
        protected Icon getIconForItem() {
            if (isTfsProject(getItem()))
                return new ImageIcon(getClass().getResource("/images/common/tfs_project.png"));
            if (isGitProject(getItem()))
                return new ImageIcon(getClass().getResource("/images/common/git_repo.png"));

            return null;
        }

    }

}